/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.mall.util.jsp.JspCacheManager
   Module Description   :

   Date Created      : 2010/1/7
   Original Author   : andy.chuang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package tw.cuttle.view.jsp;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import tw.cuttle.CuttleContext;




/**
 * @author andy.chuang
 *
 */
public class JspCacheManager {
    private static Map<String, Integer> timeoutMap=new HashMap<String, Integer>();
    private static Map<String, Long> cachedTimeMap=new HashMap<String, Long>();
    private static Map<String, String> cacheMap=new HashMap<String, String>();
    /**
     * @return the timeoutMap
     */
    public static Map<String, Integer> getTimeoutMap() {
        return timeoutMap;
    }
    /**
     * @param timeoutMap the timeoutMap to set
     */
    public static void setTimeoutMap(Map<String, Integer> timeoutMap) {
        JspCacheManager.timeoutMap = timeoutMap;
    }
    /**
     * @return the cachedTimeMap
     */
    public static Map<String, Long> getCachedTimeMap() {
        return cachedTimeMap;
    }
    /**
     * @param cachedTimeMap the cachedTimeMap to set
     */
    public static void setCachedTimeMap(Map<String, Long> cachedTimeMap) {
        JspCacheManager.cachedTimeMap = cachedTimeMap;
    }
    /**
     * @return the cacheMap
     */
    public static Map<String, String> getCacheMap() {
        return cacheMap;
    }
    /**
     * @param cacheMap the cacheMap to set
     */
    public static void setCacheMap(Map<String, String> cacheMap) {
        JspCacheManager.cacheMap = cacheMap;
    }
    private Log LOGGER=LogFactory.getLog(JspCacheManager.class);

    
    public String getKey(String cacheId, String url, String appendParameter, Map<String, String> requestMap){
	if(requestMap==null)requestMap=new HashMap<String, String>();
	String uri=url;
	if(url.indexOf("?")>=0){
	uri=url.substring(0, url.indexOf("?"));
	}
	String queryString=url.substring(url.indexOf("?")+1, url.length());
	
	StringBuffer sb=new StringBuffer("");
	if(cacheId!=null && cacheId.length()>0){
	    sb.append(cacheId);
	}else{
	    sb.append(uri);
	}
	if(appendParameter!=null){
	    String[] parameters=appendParameter.split(",");
	    String[] queryStringSplit=queryString.split("&");
	    for(int i=0;i<queryStringSplit.length;i++){
		String[] pvPair=queryStringSplit[i].split("=");
		if(pvPair.length>1)
		requestMap.put(pvPair[0], pvPair[1]);
	    }
	    sb.append("Q");
	    for(int i=0;i<parameters.length;i++){
		if(i!=0){
		    sb.append("A");
		}
		sb.append(parameters[i]).append("E");
		String value=(String)requestMap.get(parameters[i]);
		if(value!=null)sb.append(value);
	    }
	}
	String key=sb.toString();
	key=key.replaceAll("/", "S");
	return key;
    }
    public static void main(String args[]){
	JspCacheManager jc=new JspCacheManager();
	Map<String, String> requestMap=new HashMap<String, String>();
	requestMap.put("a1", "v1");
	String key=jc.getKey(null, "test.do?p1=2&p2=3", "p1,a1", requestMap);
	System.out.println(key);
	System.out.println(key.indexOf("?"));

    }
    
    public void addFileCache(String key, String content, Integer timeout){
	try{
	    saveFile(key, content);
	    timeoutMap.put(key, timeout);
	    cachedTimeMap.put(key, new Date().getTime());
	}catch(Exception e){
	    e.printStackTrace();
	    LOGGER.warn("add file cache failed! key:"+key);
	}
	
    }
    public void addCache(String key, String content, Integer timeout){
	cacheMap.put(key, content);
	timeoutMap.put(key, timeout);
	cachedTimeMap.put(key, new Date().getTime());
	
    }
    public String getContent(String cacheId, String url, String appendParameter, Map<String, String> requestMap){
	String key=getKey(cacheId, url, appendParameter, requestMap);
	return cacheMap.get(key);
    }
    public File getFileContent(String cacheId, String url, String appendParameter, Map<String, String> requestMap){
	return new File(CuttleContext.getBeanHolder().getSetting().getEnv().getCacheFolder()+"/"+getKey(cacheId, url, appendParameter, requestMap)+".htm");
    }
    public synchronized void saveFile(String key, String content)throws Exception{
	if(content==null || content.indexOf("The requested resource")>=0){
	    LOGGER.warn("The requested resource is not available");
	    return;
	}
	File folder=new File(CuttleContext.getBeanHolder().getSetting().getEnv().getCacheFolder());
	if(!folder.exists()){
	    folder.mkdirs();
	}
	String savePath=CuttleContext.getBeanHolder().getSetting().getEnv().getCacheFolder()+"/"+key+".htm";
	
        File file=new File(savePath);
        if(!file.exists()){
    		file.createNewFile();
    	}
    	InputStream is=new ByteArrayInputStream(content.getBytes());
    	OutputStream os=new FileOutputStream(savePath);
    	int length=0;
    	if(is!=null)  {
    		byte[] buf = new byte[8192];
    		
    		while (((length = is.read(buf)) != -1))  {	
    			
    			os.write(buf,0, length);		
    		}		 
    		is.close();	 
    		
    		os.flush();
    		os.close();
    		is.close();
    	}
    }
    public Boolean isTimeout(String cacheId, String key, Integer timeout){
	
	Long cachedTime=Long.valueOf(-1);
	if(cacheId!=null && cacheId.length()>0){
	    cachedTime=cachedTimeMap.get(cacheId);
	}else{
	    cachedTime=cachedTimeMap.get(key);
	}
	if(cachedTime==null || CuttleContext.getActionContext().getAccessTime().longValue()-cachedTime.longValue()>timeout){
	    System.out.println("----key:"+key+";"+"isTimeout:true");
	    return true;
	}else{
	    System.out.println("----key:"+key+";"+"isTimeout:false");
	    return false;
	}
    }

}
